<?php
import("com.yamvc.ClassNotFoundException");
class Yamvc {
	/**
	 * Singleton
	 *
	 * @var Yamvc
	 */
	private static $_instance;
	private function __construct(){
		$this->_libraryLoader = new LibLoader();
	}
	/**
	 * Enter description here...
	 *
	 * @return Yamvc
	 */
	public static function instnce(){
		if(self::$_instance==null){
			self::$_instance = new Yamvc();
		}
		return self::$_instance;
	}
	
	/**
	 * Enter description here...
	 *
	 * @var LibLoader
	 */
	private $_libraryLoader;
	public function addLibPath($value){
		$this->_libraryLoader->addLibPath($value);
	}
	public function loadLibrary($path){
		$this->_libraryLoader->load($path);
	}
	public function getClassesInClassPath($path){
		return $this->_libraryLoader->getClassesInClassPath($path);
	}
	public function errorHandler(){
		$stackTrace=null;
		try {
			$this->stackTraser();
		}catch (Exception $e){
			$stackTrace = $e->getTrace();
			$args = $stackTrace[1]['args'];
			$stackTrace = array_slice($stackTrace,2);
			$this->exceptionView($stackTrace,$args);
		}
	}
	
	public function exceptionHandler(Exception $e){
		//var_dump($e->getTrace());
		$this->stackFileLoad(array("file"=>$e->getFile(),"line"=>$e->getLine()));
		$this->exceptionView($e->getTrace(),array(null,$e->getMessage(),null,$e->getLine()));
		
	}
	
	private function exceptionView(array $stackTrace,array $args=null){
		//var_dump($stackTrace);
		//var_dump($args);
		if ($args!==null) {
			echo "ERROR IN LINE '".$args[3]."'<br />\n";
			echo "Error is ".$args[1]."<br />\n";
		}
		echo "Stack Trace: <br />\n";
		foreach ($stackTrace as $item){
			$this->stackFileLoad($item);
		}
		exit;
	}
	
	private function stackFileLoad(array $stackItem){
		$fileName = str_replace("\\","/",$stackItem['file']);
		echo $fileName;
		$file = fopen($fileName,"r");
		$lineCounter=0;
		echo "<table>";
		while (!feof($file)){
			$lineCounter++;
			if ($lineCounter>=$stackItem['line']-2){
				if ($lineCounter==$stackItem['line']){
					echo "<tr style='background-color:#ffdddd'>";
				}else {
					echo "<tr>";
				}
					echo "<td>";
						echo "<pre>".$lineCounter."</pre>";
					echo "</td>"; 
					echo "<td>";
						echo "<pre>".htmlspecialchars(fgets($file))."</pre>";
					echo "</td>";
				echo "</tr>";
				if ($lineCounter==$stackItem['line']+1){
					break;
				}
			}else{
				fgets($file);
			}
		}
		echo "</table>";
	}
	
	private function stackTraser(){
		throw new Exception();
	}
	
	public function initApplication(){
		
	}
}

class LibLoader{
	const EXTENSION="class";
	private $_path=array('./libs/');
	public function addLibPath($value){
		if(!is_string($value)) throw new ArgumentException();
		if(!in_array($value,$this->_path)){
			array_push($this->_path,$value);
		}
	}
	public function load($path){
		$path = str_replace(".","/",$path);
		$path = $path.".".LibLoader::EXTENSION.".php";
		foreach ($this->_path as $p){
			if(file_exists($p.$path)){
				require_once ($p.$path);
				return;
			}
		}
		throw new ClassNotFoundException($path);
	}
	
	public function getClassesInClassPath($path){
		$path = str_replace(".","/",$path);
		$classes = array();
		foreach ($this->_path as $base) {
			if (is_dir($base.$path)){
				$dir = dir($base.$path);
				while(false !== ($item=$dir->read())){
					if (stripos($item,".class.php")){
						array_push($classes,str_replace(".class.php","",$item));
					}
				}
				return $classes;
			}
		}
		 
	}
}

function import($path){
	Yamvc::instnce()->loadLibrary($path);
}
///// BOOTSTRAP //////////
ini_set("display_errors",true);
error_reporting(E_ALL);
set_error_handler(array(Yamvc::instnce(),"errorHandler"));
set_exception_handler(array(Yamvc::instnce(),"exceptionHandler"));



?>